#include "sys.h"
#include "cpuid.h"

//加密后的CPUID  
// 加上volatile修饰符后，则么读都不正常，条件永远成立；去掉volatile后，直接读也不正常，需要*(&CPUIDEncrypt)这样读才可以。
 const  u32 CPUIDEncrypt = 0xFFFFFFFF;   
 
// 设置读保护
void FlashReadOutLock(void)
{
    if (FLASH_OB_GetRDP() != OB_RDP_LEVEL_1)
    {
        HAL_FLASH_Unlock();    //解锁Flash和选项字节
        HAL_FLASH_OB_Unlock(); 

        FLASH_OBProgramInitTypeDef obInit;
        obInit.OptionType = OPTIONBYTE_RDP;
        obInit.RDPLevel = OB_RDP_LEVEL_1;  //启用读保护
        HAL_FLASHEx_OBProgram(&obInit);
        HAL_FLASH_OB_Launch();            //更新配置     
    
        HAL_FLASH_OB_Lock();        //锁定Flash和选项字节
        HAL_FLASH_Lock();
    }
}

// 解除读保护
void FlashReadOutUnlock(void)
{
    if (FLASH_OB_GetRDP() != OB_RDP_LEVEL_0)
    {
        HAL_FLASH_Unlock();
        HAL_FLASH_OB_Unlock();

        FLASH_OBProgramInitTypeDef obInit;
        obInit.OptionType = OPTIONBYTE_RDP;
        obInit.RDPLevel = OB_RDP_LEVEL_0;
        HAL_FLASHEx_OBProgram(&obInit);

        HAL_FLASH_OB_Launch();

        HAL_FLASH_OB_Lock();
        HAL_FLASH_Lock();
    }
}

//写入加密数据  
void WriteEncrypt(void)  
{   
	  //第一次烧写:将UID写入到Flash中  
    if(*(&CPUIDEncrypt)==0xFFFFFFFF)  
    {  
         u32 CpuID[3];     
			
         //获取CPU唯一的ID  
         CpuID[0]=*(u32*)(CPUID_BASEADDR);  
         CpuID[1]=*(u32*)(CPUID_BASEADDR+4);  
         CpuID[2]=*(u32*)(CPUID_BASEADDR+8);          
   
         //加密算法,很简单的加密算法  
         u32 EncryptCode=(CpuID[0]>>3)+(CpuID[1]>>1)+(CpuID[2]>>2);     
         HAL_FLASH_Unlock();  
         __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_BSY|FLASH_FLAG_EOP|FLASH_FLAG_PGAERR|FLASH_FLAG_PGSERR|FLASH_FLAG_PGPERR|FLASH_FLAG_WRPERR);  // 清除标志位
			//   FLASH_ErasePage((U32)(&CPUIDEncrypt));  //擦除一页，所以不能这样擦除，否则把自己的程序擦掉了
         HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,(u32)(&CPUIDEncrypt), EncryptCode);  
         HAL_FLASH_Lock();  
     }  
 }  
 //判断加密  
 u8 JudgeEncrypt(void)  
 {         
     u32 CpuID[4];      
   
     //获取CPU唯一的ID  
     CpuID[0]=*(u32*)(CPUID_BASEADDR);  
     CpuID[1]=*(u32*)(CPUID_BASEADDR+4);  
     CpuID[2]=*(u32*)(CPUID_BASEADDR+8); 
	 
     //加密算法,很简单的加密算法  
     CpuID[3]=(CpuID[0]>>3)+(CpuID[1]>>1)+(CpuID[2]>>2); 
	 
     //检查Flash中的UID是否合法   
     if (*(&CPUIDEncrypt) == CpuID[3])
     {
          return 0;
		 }
     else
		 {
          return 1;
		 }			 
 }  
 
